package com.xuecheng.ucenter.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.auth.config.ALiYunSMSConfig;
import com.xuecheng.auth.config.EmailConfig;
import com.xuecheng.ucenter.mapper.XcUserMapper;
import com.xuecheng.ucenter.mapper.XcUserRoleMapper;
import com.xuecheng.ucenter.model.dto.AuthParamsDto;
import com.xuecheng.ucenter.model.dto.XcUserExt;
import com.xuecheng.ucenter.model.po.XcUser;
import com.xuecheng.ucenter.model.po.XcUserRole;
import com.xuecheng.ucenter.service.AuthService;
import com.xuecheng.ucenter.service.SMSService;
import com.xuecheng.utils.RegexUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service("sms_authservice")
@Slf4j
public class SMSServiceImpl implements SMSService, AuthService {

    @Autowired
    ALiYunSMSConfig aLiYunSMSConfig;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired(required = false)
    XcUserMapper xcUserMapper;
    @Autowired(required = false)
    XcUserRoleMapper xcUserRoleMapper;
    //短信签名
    @Value("${aliyun.sms.SignName}")
    private String SignName;
    @Value("${aliyun.sms.TemplateCode}")
    private String TemplateCode;

    public void sendSms(String phoneNumbers) throws Exception {
        //通过手机号找回密码
        boolean mobile = RegexUtils.isMobile(phoneNumbers);
        if(mobile==true){
            log.info("通过手机号找回密码:{}",phoneNumbers);
            sendPhone(phoneNumbers);
            return;
        }
        //通过邮箱找回密码
        boolean email = RegexUtils.isEmail(phoneNumbers);
        if(email==true){
            log.info("通过邮箱找回密码：{}",phoneNumbers);
            sendEmail(phoneNumbers);
            return;
        }

        throw new Exception("请输入手机号或邮箱！");
    }

    //邮箱重置密码
    public void sendEmail(String email){
        //生成验证码，发送验证码
        String verificationCode = randomCode();
        Set<String> set = new HashSet<>();
        set.add(email);
        log.info("向{}发送消息",email);
        EmailConfig.sendEmail(set, "测试发送邮件验证码接口！",
                "您好！这是我发送的一封测试发送接口的邮件，看完请删除记录。验证码为:"+verificationCode+"，3分钟内有效");

        //将验证码存入redis,3分钟过期
        stringRedisTemplate.opsForValue().set(email,verificationCode,3, TimeUnit.MINUTES);

    }
    //手机号重置密码
    public void sendPhone(String phoneNumbers) throws Exception {
        //检验手机号
        boolean mobile = RegexUtils.isMobile(phoneNumbers);

        String verificationCode = randomCode();
        //拼接阿里云短信模板变量对应的实际值"{\"code\":\"+verificationCode+\"}";
        HashMap hashMap = new HashMap();
        hashMap.put("code", verificationCode);
        String templateParam = JSON.toJSONString(hashMap);
        //配置发送阿里云短信的请求体
        SendSmsRequest sendSmsRequest=new SendSmsRequest();
        //设置短信签名名称
        sendSmsRequest.setSignName(SignName);
        //设置短信模板Code
        sendSmsRequest.setTemplateCode(TemplateCode);
        //设置发送短信的手机号
        sendSmsRequest.setPhoneNumbers(phoneNumbers);
        //设置短信模板变量对应的实际值
        sendSmsRequest.setTemplateParam(templateParam);
        //发送短信响应体
        SendSmsResponse sendSmsResponse=null;
        try {
            //调用阿里云短信服务发送短信验证码
            sendSmsResponse = sendShortMessage(sendSmsRequest);
            log.info("调用阿里云短信服务发送短信验证码");
        } catch (Exception e) {
            throw new Exception("调用阿里云短信服务发送短信验证码接口失败！", e);
        }
        if (!sendSmsResponse.getBody().getCode().equals("OK")) {
            log.error("调用阿里云短信服务发送短信验证码失败 {}", sendSmsResponse);

        }
        log.info("调用阿里云短信服务发送短信验证码成功 {}", sendSmsResponse);
        //将验证码存入redis,5分钟过期
        stringRedisTemplate.opsForValue().set(phoneNumbers,verificationCode,5, TimeUnit.MINUTES);

        //第添加手机用户--当用手机号登录时需要添加用户，此项目为用密码与扫码登录
//        addPhoneUser(phoneNumbers);
    }

    //随机验证码
    public static String randomCode() {
        StringBuffer  stringBuffer = new StringBuffer ();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            stringBuffer.append(random.nextInt(10));
        }
        return stringBuffer.toString();
    }
    //发送验证码
    public  SendSmsResponse sendShortMessage(SendSmsRequest sendSmsRequest) throws Exception {
        //TODO 配置运行时间选项暂时未进行配置
        RuntimeOptions runtime = new RuntimeOptions();
        com.aliyun.dysmsapi20170525.Client client= aLiYunSMSConfig.createClient();
        SendSmsResponse sendSmsResponse;
        try {
            //发送短信
            sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
        } catch (Exception e) {
            throw new Exception("调用阿里云发送短信接口失败", e);
        }
        log.info("调用阿里云发送短信接口成功");
        return sendSmsResponse;
    }
    //添加用户信息
    @Transactional
    public XcUser addPhoneUser(String phoneNumbers){
        //根据手机号查询数据库
        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, phoneNumbers));
        if(xcUser!=null){
            return xcUser;
        }
        String userId = UUID.randomUUID().toString();
        xcUser = new XcUser();
        xcUser.setId(userId);
        //用手机号作为名称
        xcUser.setUsername(phoneNumbers);
        xcUser.setName(phoneNumbers);
        xcUser.setUtype("101001");//学生类型
        xcUser.setStatus("1");//用户状态
        xcUser.setCreateTime(LocalDateTime.now());
        xcUserMapper.insert(xcUser);
        XcUserRole xcUserRole = new XcUserRole();
        xcUserRole.setId(UUID.randomUUID().toString());
        xcUserRole.setUserId(userId);
        xcUserRole.setRoleId("17");//学生角色
        xcUserRoleMapper.insert(xcUserRole);
        return xcUser;
    }


    /**
     * 验证手机验证码
     * @param authParamsDto 认证参数
     * @return
     */
    @Override
    public XcUserExt execute(AuthParamsDto authParamsDto) {
        //手机号
        String cellphone = authParamsDto.getCellphone();
        //验证码
        String checkcode = authParamsDto.getCheckcode();
        //从redis查询
        String s = stringRedisTemplate.opsForValue().get(cellphone);
        if(s==null||!s.equals(checkcode)){
            throw new RuntimeException("验证码错误!");
        }
        //账号
        String username = authParamsDto.getUsername();
        XcUser user = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username));
        if(user==null){
            //返回空表示用户不存在
            throw new RuntimeException("账号不存在");
        }
        XcUserExt xcUserExt = new XcUserExt();
        BeanUtils.copyProperties(user,xcUserExt);
        return xcUserExt;
    }
}
